﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
 

namespace nadModel
{
    [Serializable]
    public abstract class AbstractEntity
    {
        protected const string _CREATED_BY_FIELD = "created_by";
        protected const string _CREATED_DATETIME_FIELD = "created_datetime";
        protected int _ENTITY_FIELD_COUNT;
        protected string _ENTITY_FIELDS = "";
        protected int _ENTITY_TABLE_COUNT;
        protected string _ENTITY_TABLES = "";
        protected const string _UPDATED_BY_FIELD = "updated_by";
        protected const string _UPDATED_DATETIME_FIELD = "updated_datetime";
        protected List<string> dirtyFields = new List<string>();
        public string LinkedServerID;

        public void ClearDirty(string field)
        {
            if (this.dirtyFields.Contains(field))
            {
                this.dirtyFields.Remove(field);
            }
        }

        public abstract AbstractEntity Clone();

        public string FieldNameToPropertyName(string dbName)
        {
            StringBuilder builder = new StringBuilder();
            bool flag = false;
            for (int i = 0; i < dbName.Length; i++)
            {
                if (dbName[i] == '_')
                {
                    flag = true;
                }
                else if ((i != 0) && !flag)
                {
                    builder.Append(dbName[i]);
                }
                else
                {
                    char ch = dbName[i];
                    builder.Append(ch.ToString().ToUpper());
                    flag = false;
                }
            }
            return builder.ToString();
        }

        public bool Equals(AbstractEntity e)
        {
            Type o = base.GetType();
            if (!e.GetType().Equals(o))
            {
                return false;
            }
            string[] strArray = this._ENTITY_FIELDS.Split(new char[] { ',' });
            int index = 0;
            while (index < strArray.Length)
            {
                strArray[index] = FieldNameToPropertyName(strArray[index].Trim());
                PropertyInfo property = o.GetProperty(strArray[index]);
                if ((property.GetValue(this, null) == null) && (property.GetValue(e, null) != null))
                {
                    return false;
                }
                if ((property.GetValue(this, null) != null) && (property.GetValue(e, null) == null))
                {
                    return false;
                }
                if (!property.GetValue(this, null).Equals(property.GetValue(e, null)))
                {
                    return false;
                }
                index++;
            }

            return true;
        }

        public string[] GetFieldList()
        {
            string[] strArray = this._ENTITY_FIELDS.Split(new char[] { ',' });
            int index = 0;
            while (index < strArray.Length)
            {
                strArray[index] = strArray[index].Trim();
                index++;
            }

            return strArray;
        }

        public virtual string[] GetSystemFields()
        {
            return new string[] { "PKey", "ENTITY_FIELDS", "ENTITY_FIELD_COUNT", "ENTITY_TABLES", "ENTITY_TABLE_COUNT", "CREATED_DATETIME_FIELD", "UPDATED_DATETIME_FIELD", "CREATED_BY_FIELD", "UPDATED_BY_FIELD" };
        }

        public void MarkClean()
        {
            this.dirtyFields.Clear();
        }

        public void MarkDirty(string field)
        {
            if (!this.dirtyFields.Contains(field))
            {
                this.dirtyFields.Add(field);
            }
        }
        public string CREATED_BY_FIELD
        {
            get
            {
                return "created_by";
            }
        }

        public string CREATED_DATETIME_FIELD
        {
            get
            {
                return "created_datetime";
            }
        }

        public List<string> DirtyFields
        {
            get
            {
                return this.dirtyFields;
            }
        }

        public int ENTITY_FIELD_COUNT
        {
            get
            {
                return this._ENTITY_FIELD_COUNT;
            }
        }

        public string ENTITY_FIELDS
        {
            get
            {
                return this._ENTITY_FIELDS;
            }
        }

        public int ENTITY_TABLE_COUNT
        {
            get
            {
                return this._ENTITY_TABLE_COUNT;
            }
        }

        public string ENTITY_TABLES
        {
            get
            {
                if (string.IsNullOrEmpty(this.LinkedServerID))
                {
                    return this._ENTITY_TABLES;
                }
                return "";
            }
        }

        public abstract AbstractEntityPKey PKey { get; }

        public string UPDATED_BY_FIELD
        {
            get
            {
                return "updated_by";
            }
        }

        public string UPDATED_DATETIME_FIELD
        {
            get
            {
                return "updated_datetime";
            }
        }

    }
}
